package com.my.stock.core;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;

import util.JavaFile;

public class BayeMain {
	public static void main1(String[] args) throws IOException {
		NormalDistribution nd = new NormalDistribution(0, 1);
		double dd = nd.cumulativeProbability(1, 2);
		System.out.print(dd);
		
		
	}
	
	
	public static void main(String[] args) throws IOException {

//		NormalDistribution nd = new NormalDistribution(0.483, 0.283);
//		double dd = nd.density(1.36);
//		double dd1 = Bayes.gaussian(400.0, 242.0, 203.0);
//
//		System.out.println(nd.cumulativeProbability(400, 2000));
//		System.out.println(Bayes.integrateGaussian(578.65-7.08,578.65+7.08, 578.65, 7.08));
		int count = 0;
		int rightCount = 0;
		int wrongCount = 0;
		List<String> list = JavaFile.readfile("d:\\i2501buy.txt");
		String data = JavaFile.readfileToStringN("d:\\i2501buy.txt");
		String lastBet = "";
		Bayes bayes = new Bayes(data);
		for (String x : list) {
//			if (x.split(",")[1].equals("090")) {
//				continue;
//			}

			String from = x.split(",")[12];

			List<String> result = bayes.main(x.split(",")[0] + "," + x.split(",")[1] + "," + x.split(",")[2] + ","
					+ x.split(",")[3] + "," + x.split(",")[4] + "," + x.split(",")[5] + "," + x.split(",")[6] + ","
					+ x.split(",")[7] + "," + x.split(",")[8] + "," + x.split(",")[9] + "," + x.split(",")[10] + ","
					+ x.split(",")[11]);

			count++;

//			if (lastBet.equals(x.split(",")[2])) {
//				continue;
//			}
//
//			if (x.split(",")[2].equals("090")) {
//				continue;
//			}
			if (result.get(0).equals("+++++++")) {
//			if (Double.parseDouble(result.get(1)) <0.01) {
				if (from.equals(result.get(0))) {
//					System.out.println(x);
					rightCount++;
				} else {
//					System.out.println(x);
					wrongCount++;
				}
			}

//			}

			lastBet = x.split(",")[2];
		}
		System.out.println(rightCount + "/" + wrongCount + "/" + count);
	}
}

class Bayes {

	// 计算高斯函数在[a, b]区间的一阶梯形求积分
	public static double integrateGaussian(double a, double b, double mu, double sigma) {
		return (b - a) / 2 * (gaussian(a, mu, sigma) + gaussian(b, mu, sigma));
	}

	public static double gaussian(double x, double mean, double stdDeviation) {
		double exponent = Math.pow(x - mean, 2) / (2 * Math.pow(stdDeviation, 2));
		double coefficient = 1 / Math.sqrt(2 * Math.PI * Math.pow(stdDeviation, 2));
		return coefficient * Math.exp(-exponent);
	}

	private String dataInput;

	private DescriptiveStatistics stats1[];
	private DescriptiveStatistics stats2[];
	private List<List<String>> data;
	private int colNum;
	private int rowNum;
	private Map<String, Integer> values;

	public Bayes(String dataInput) {
		data = getData(dataInput);
		stats1 = new DescriptiveStatistics[data.get(0).size() - 1];
		stats2 = new DescriptiveStatistics[data.get(0).size() - 1];
		rowNum = data.size();
		colNum = data.get(0).size();

		for (int i = 0; i < data.size(); i++) {
			List<String> oneRow = data.get(i);

			for (int j = 0; j < oneRow.size() - 1; j++) {

				if (stats1[j] == null) {
					stats1[j] = new DescriptiveStatistics();
				}
				if (stats2[j] == null) {
					stats2[j] = new DescriptiveStatistics();
				}
				if (oneRow.get(12).equals("+++++++")) {
					stats1[j].addValue(Double.parseDouble(oneRow.get(j)));
				} else {
					stats2[j].addValue(Double.parseDouble(oneRow.get(j)));
				}

			}
		}
		values = getValuesAndCount(data, colNum - 1);

	}

	public List<String> main(String xInput) {

		// 获取最后一列可能的属性以及个数
		List<String> x = getData(xInput).get(0);

		// 求结果，并比大小
		Set<String> keys = values.keySet();
		double[] p = new double[keys.size()];
		List<String> keyList = new ArrayList<>(keys);
		int maxIndex = 0;
		double maxValue = -1;
		// 对于最后一行的每一个可能的值遍历
		for (int i = 0; i < keyList.size(); i++) {
			String key = keyList.get(i);
			Integer count = values.get(key);
			p[i] = 1.0 * count / rowNum;

			for (int j = 0; j < x.size() - 1; j++) {

				
//				if (j != 8) {
//					continue;
//				}


				DescriptiveStatistics ds = null;

				if (key.equals("+++++++")) {
					ds = stats1[j];
				} else {
					ds = stats2[j];
				}

				double gp = gaussian(Double.parseDouble(x.get(j)), ds.getMean(), ds.getStandardDeviation());
//				System.out.println(gp);
				if (gp == 0) {
					System.out.println(x.get(j) + "  " + ds.getMean() + "  " + ds.getStandardDeviation());
				}
				p[i] *= gp;
//				System.out.println(p[i] );
			}

//			List<List<String>> filter = filter(data, colNum - 1, key, 12, x.get(12));
//			p[i] *= filter.size() * 1.0 / count;

			// 找最大的那一列
			if (p[i] > maxValue) {
				maxIndex = i;
				maxValue = p[i];
			}

		}
//		System.out.println(keyList.get(maxIndex) + maxValue);
		List<String> resultList = new ArrayList<String>();
		resultList.add(keyList.get(maxIndex));
		resultList.add(String.valueOf(p[0] / p[1]));
		return resultList;
	}

	private List<List<String>> filter(List<List<String>> data, int col1, String colValue1, int col2, String colValue2) {
		return data.stream().filter(d -> colValue1.equals(d.get(col1)) && colValue2.equals(d.get(col2)))
				.collect(Collectors.toList());
	}

	private Map<String, Integer> getValuesAndCount(List<List<String>> data, int index) {
		Map<String, Integer> map = new HashMap<>();
		data.forEach(d -> {
			String colStr = d.get(index);
			Integer orDefault = map.getOrDefault(colStr, 0);
			map.put(colStr, orDefault + 1);
		});
		return map;
	}

	List<List<String>> getData(String s) {
		if (!s.contains(";")) {
			s = s.replaceAll("\r\n", ";");
		}

		List<List<String>> res = new ArrayList<>();
		String[] row = s.split(";");
		for (String r : row) {
			List<String> rowList = new ArrayList<>();
			for (String col : r.split(",")) {
				rowList.add(col);
			}
			res.add(rowList);
		}

		return res;
	}
}
